#ifndef BIG_INT_H
#define BIG_INT_H

#include <fstream>
#include <iostream>
#include <string>
#include <ios>
#include <assert.h>

#include "digits_container.h"



struct big_int
{     
public:
   static const int EXTERNAL_BASE = 10;
   static const int BASE = 1000*1000*1000;
   static const int K = 9;
   
   big_int():
      is_positive(true)
   {
      digits.push_back(0);
   }

   big_int(long long);

   explicit big_int(const std::string& s);

   big_int operator-();

   big_int& operator+=(const big_int&);

   big_int& operator-=(const big_int&);
   
   big_int& operator*=(const big_int&);

   big_int& operator/=(const big_int&);

   big_int& operator%=(const big_int&);

   big_int abs();
   int compare(const big_int& b, int shift);

   void swap(big_int&);

   
   friend std::istream& operator>>(std::istream&, big_int&);
   friend std::ostream& operator<<(std::ostream&, const big_int&);
   

private:
   digits_container digits;
   bool is_positive;

   std::pair<big_int, big_int> qoutient_and_remainder_division(const big_int& a1, const big_int& b1);
   void subtract(big_int&, const big_int&, int sgift);
   void delete_leading_zeros();
   void fix_sign();
   
};

int compare(big_int a, const big_int& b, int shift);

bool operator<(const big_int&, const big_int&);

bool operator>(const big_int&, const big_int&);

bool operator==(const big_int&, const big_int&);

bool operator!=(const big_int&, const big_int&);

bool operator<=(const big_int&, const big_int&);

bool operator>=(const big_int&, const big_int&);

big_int operator+(const big_int&, const big_int&);

big_int operator-(const big_int&, const big_int&);

big_int operator*(const big_int&, const big_int&);

big_int operator/(const big_int&, const big_int&);

big_int operator%(const big_int&, const big_int&);

big_int abs(const big_int& x);

#endif
